package org.apache.ocean.solr.search;

import java.io.IOException;

import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.TermEnum;
import org.apache.lucene.search.DocIdSetIterator;
import org.apache.ocean.main.Index.FieldCursor;
import org.apache.ocean.main.Index.IndexSnapshot;
import org.apache.ocean.main.fields.FieldType;
import org.apache.ocean.main.util.Range;

public class FieldCursorImpl extends FieldCursor {
  private String field;
  private TermEnum termEnum;
  private IndexSnapshot indexSnapshot;
  private FieldType fieldType;
  boolean checkLower = false;
  private String lowerTerm;
  private String upperTerm;
  private Range range;

  public FieldCursorImpl(String f, Range range, IndexSnapshot indexSnapshot)
      throws IOException {
    field = f.intern();
    this.range = range;
    this.indexSnapshot = indexSnapshot;
    fieldType = indexSnapshot.getIndexSchemaCategory().getFieldType(field);
    lowerTerm = fieldType.objectToIndexed(range.getLowerVal());
    upperTerm = fieldType.objectToIndexed(range.getUpperVal());
    IndexReader indexReader = indexSnapshot.getIndexReader();
    if (range.isIncludeLower()) {
      checkLower = true;
    }
    termEnum = (null != lowerTerm ? indexReader.terms(
        new Term(field, lowerTerm), true) : indexReader.terms(new Term(field,
        ""), true));
  }

  public Object value() throws Exception {
    Term term = termEnum.term();
    return fieldType.indexedToObject(term.text());
  }

  public DocIdSetIterator docs() throws Exception {
    return termEnum.docs();
  }
  
  public void close() throws Exception {
    termEnum.close();
  }
  
  public boolean next() throws Exception {
    do {
      Term term = termEnum.term();
      if (term != null && term.field() == field) {
        if (!checkLower || null == lowerTerm
            || term.text().compareTo(lowerTerm) > 0) {
          checkLower = false;
          if (upperTerm != null) {
            int compare = upperTerm.compareTo(term.text());
            /*
             * if beyond the upper term, or is exclusive and this is equal to
             * the upper term, break out
             */
            if ((compare < 0) || (!range.isIncludeUpper() && compare == 0)) {
              return false;
            }
          }
          return true;
          /* we have a good term, find the docs */
          // DocIdSetIterator docsIterator = termEnum.docs();
          // while (docsIterator.next()) {
          // bits.set(docsIterator.doc());
          // }
        }
      }
      return false;
    } while (termEnum.next());
  }
}